package server

import (
	"fmt"
	"net"
	"reflect"
	"rpc_server_demo/tools"
)

// 声明服务端
type Server struct {
	// 地址
	addr string
	// map 用于维护关系的
	funcs map[string]reflect.Value
}

// NewServer 构造函数
func NewServer(addr string) *Server {
	return &Server{
		addr:  addr,
		funcs: make(map[string]reflect.Value),
	}
}

// Register 服务注册方法
func (s *Server) Register(rpcName string, f interface{}) {
	//维护一个map，如果没值就写入值
	if _, ok := s.funcs[rpcName]; ok {
		return
	}
	fVal := reflect.ValueOf(f)
	s.funcs[rpcName] = fVal
}

// Run 服务等待调用
func (s *Server) Run() {
	//监听
	listen, err := net.Listen("tcp", s.addr)
	if err != nil {
		fmt.Printf("监听 %s err :%v", s.addr, err)
		return
	}
	for {
		conn, err := listen.Accept()
		if err != nil {
			fmt.Println("accept:", err)
			return
		}
		serverSession := tools.NewSession(conn)
		//读取数据
		data, err := serverSession.Read()
		if err != nil {
			fmt.Println("read:", err)
			return
		}
		//解码
		rpcData, err := tools.Decode(data)
		if err != nil {
			fmt.Println("decode:", err)
			return
		}
		//检查要调用的函数是否存在
		f, ok := s.funcs[rpcData.Name]
		if !ok {
			fmt.Printf("函数%s不存在\n", rpcData.Name)
			return
		}
		//遍历解析客户端传来的参数，放到切片里
		inArgs := make([]reflect.Value, 0, len(rpcData.Args))
		for _, v := range rpcData.Args {
			inArgs = append(inArgs, reflect.ValueOf(v))
		}
		out := f.Call(inArgs)
		outArgs := make([]interface{}, 0, len(out))
		for _, v := range out {
			outArgs = append(outArgs, v.Interface())
		}
		respData := tools.RPCData{
			Name: rpcData.Name,
			Args: outArgs,
		}
		fmt.Println(respData)
		bytes, err := tools.Encode(respData)
		if err != nil {
			fmt.Println("encode err,",err)
			return
		}
		err = serverSession.Write(bytes)
		if err != nil {
			return
		}
	}
}
